
#include <iostream>
#include <errno.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string>
#include <vector>
#include <sys/dispatch.h>
#include <semaphore.h>

#ifndef COMMUNICATION_H
#define COMMUNICATION_H


/** komunikaty DATABASE <- **/

#define GET_AIRPORTS_EV_DB 				121
#define RES_GET_AIRPORTS_EV_DB		122
#define  GET_AIRPORTS_PL_DB 			123
#define  GET_PLANES_EV_DB 				125
#define  RES_GET_PLANES_EV_DB 		126
#define  GET_EVENTS_EV_DB 				127
#define  RES_GET_EVENTS_EV_DB 		128
#define GET_AIRPORT_AI_DB 				129
#define RES_GET_AIRPORT_AI_DB			130

#define  GET_PLANE_AI_DB	 				131
#define  RES_GET_PLANE_AI_DB			132

#define  GET_AIRPORT_PL_DB 				135
#define  GET_AIRPLANE_PL_DB				136


#define FAILURE_EV_PL						141
#define FAILURE_EV_PO						140
#define FAILURE_OVER_EV_PL				142
#define FAILURE_OVER_EV_PO				143


#define ACTIVATE_AIRPORT					150
#define DISACTIVATE_AIRPORT				151

#define ZAKAZ_LADOWANIA					160
//#define  FLY_AWAY_JOHNNYB				161
#define ZAKAZ_STARTU						162

#define BD_MOD																	200
#define WIEZA_MOD																201
#define ZDARZENIA_MOD														202

#define MSG_ZGLOSZENIE_GOTOWOSCI_DO_LADOWANIA		210
#define MSG_ZGLOSZENIE_GOTOWOSCI_DO_STARTU			211
#define MSG_ZGLOSZENIE_AWARII										212 
#define MSG_STAN_PALIWA													213
#define MSG_AKTUALNA_POZYCJA											214
#define MSG_NOWA_MASZYNA_W_STREFIE							215	
#define MSG_ZAPODAJ_NAJBLIZSZE_LOTNISKO						216
#define MSG_SIE_ZESRRRALES												217
#define MSG_KONIEC_AWARII												218
#define MSG_ZEZWOLENIE_NA_START									219
#define MSG_ZMIEN_KURS													220
#define MSG_POCZEKAJ_Z_LADOWANIEM								221
#define MSG_MOZESZ_LADOWAC											222
#define MSG_OPUSCILES_STREFE_WPLYWOW						223

#define MSG_ZAPODAJ_WSPOLRZEDNE_LOTNISKA					224
#define MSG_LAP_WSPOLRZEDNE_LOTNISKA							225
		
#define MSG_PODAJ_LICZBE_LOTNISK									226
#define MSG_PRZESLIJ_LOTNISKA											227

#define MSG_LAP_LICZBE_LOTNISK										228
#define MSG_KONCZE_SMIGAC												229
#define MSG_GON_SIE															230
#define MSG_ZAPODAJ_DANE_TECHNICZNE							231
#define  MSG_SIE_ODESRALES												232

#define MSG_LAP_DANE_SAMOLOTU										233
#define MSG_POJAWIAM_SIE_NA_LOTNISKU							234


#define MSG_RES_ZAPODAJ_DANE_TECHNICZNE					233


#define CONN_NAME_LENGTH 20

using namespace std;



/* We specify the header as being at least a pulse */
typedef struct _pulse msg_header_t;

/* Our real data comes after the header */
typedef struct _my_data {

    msg_header_t hdr;
    
	int type;

	char connSenderName[CONN_NAME_LENGTH];	// nazwa kanalu, na ktorym nasluchuje nadawca 
	char connReceiverName[CONN_NAME_LENGTH];	// nazwa kanalu, na ktorym nasluchuje obiorca
	int nr;						// nr elementu w wektorze	
	int msgLength;			// dlugosc przesylanego wektora
	
	
	/** dane **/
	
	int argInt1;
	int argInt2;
	int argInt3;
	int argInt4;
	
	bool argBool1;
	
	float argFloat1;
	float argFloat2;
	float argFloat3;
	
	char argStr1[CONN_NAME_LENGTH];
	char argStr2[CONN_NAME_LENGTH];		
} my_data_t;


/**
	Klasa opakowujaca informacje do przeslania przez siec
**/
class Message {

private:
     
     
public:
	my_data_t data;
	
    /* konstruktor*/
    Message();
    
    /* ustalenie typu przysylki*/
    void setType( int _type);
    /* pobranie typu przysylki*/
    int getType( void);
	
   	char * getConnSenderName(void);
     void setConnSenderName(char* arg);
     
    char * getConnReceiverName(void);
     void setConnReceiverName(char* arg);
   
   	void setMessageLength( int arg);
   	int getMessageLength(void);
   
   void setNr( int arg);
   int getNr(void);
   
	int getIntArg1(void);
	void setIntArg1(int);   
	int getIntArg2(void);
	void setIntArg2(int);   
	int getIntArg3(void);
	void setIntArg3(int);   
	int getIntArg4(void);
	void setIntArg4(int);   
   
   	bool getBoolArg1(void);
	void setBoolArg1(bool);
	
	float getFloatArg1(void);
	void setFloatArg1(float);
	float getFloatArg2(void);
	void setFloatArg2(float);
	float getFloatArg3(void);
	void setFloatArg3(float);
	
	char * getStringArg1(void);
	void setStringArg1(char *);
	
	char * getStringArg2(void);
	void setStringArg2(char *);
	
    /* pobranie dlugosci danych w przysylce*/
    char * verboseType( int _type);
   
   /* funkcja kopiujaca Message*/
	void copyMessage ( Message * ptr);

    /* funkcja debugowa */
    void dumpMessage( void);
    
    
};




/********** przysylane typy danych ************/




/**
* Struktura reprezentujaca lotnisko.
*/
class lotnisko
{
	public:
		int id_lotniska;
		std::string nazwa;
		int pojemnosc;
		float szerokosc_geo;
		float dlugosc_geo;
		int ilosc_szerokich_pasow;
		int ilosc_waskich_pasow;
		bool aktywnosc;
};

/**
* Struktura reprezentujaca samolot.
*/
class samolot
{
	public:
		std::string nazwa;
		float bak;
		float spalanie;
		float predkosc;
		int czas_obslugi;
		bool czy_szeroki;
};

/**
* Struktura reprezentujaca zdarzenie.
*/
class zdarzenie
{
	public:
		int podtyp;
		int typ;
		std::string nazwa;
};

/**
* Struktura reprezentujaca dane samolotu przydatne z perspektywy lotniska.
*/
class samolot_dla_lotniska
{
	public:
		int czas_obslugi;
		bool czy_szeroki;
};

/**
* Struktura reprezentujaca dane samolotu przydatne z perspektywy samolotu.
*/
class samolot_dla_samolotu
{
	public:
		float bak;
		float spalanie;
		float predkosc;
};

/**
* Struktura reprezentujaca dane lotniska przydatne z perspektywy samolotu.
*/
class lotnisko_dla_samolotu
{
	public:
		int id_lotniska;
		float szerokosc_geo;
		float dlugosc_geo;
		std::string nazwa;
};







class ConnNameForPlane {
public :
    char * airportName;
	int airportId;
	
	ConnNameForPlane(int, char *);
};


class ConnFD {
public :
    char * connName;
	int fd;
	
	ConnFD(char *, int);
};



/**
	Klasa opakowujaca informacje do przeslania przez siec
**/
class Connector {

private:

	char * connName;

    static Connector * instance;
    
     // wektory na odbierane przez siec listy 
     std::vector<lotnisko>* airportsDB;
     std::vector<samolot> * planesDB;
	 std::vector<zdarzenie> * eventsDB;
	 
	  std::vector<ConnFD> * connectionsOpened;
	 
	 lotnisko * airportAI;
    Connector();
    

public:

	std::vector<ConnNameForPlane> * airportsNames;
	
	 static Connector * getInstance();    
	
	 void createListener(char * _connName);
	
	char * getConnName(void);

	 sem_t semAirportsDB;
	 sem_t semPlanesDB;
	 sem_t semEventsDB;
	 
	 sem_t semConns;
	 
	 /* funkcje pozwalajace ustawic nowy wektor na dane*/
	 void setListAirportsDB( std::vector<lotnisko>* arg);
	 void setListPlanesDB( std::vector<samolot>* arg);
	 void setListEventsDB( std::vector<zdarzenie>* arg);
	 void setAirportAI( lotnisko * arg);
	 
	 /* funkcje pozwalajace dodac element do wektora */
	void nextAirportDB( lotnisko * arg);
	void nextPlaneDB( samolot * arg);
	void nextEventDB( zdarzenie * arg);
	void airportCameAI( Message * msg);
	
	char * getAirportName( int arg);
	
	  //DEBUG
    void showMeAirports(void);
    
       int isConnected( char * arg);
       void addConn(char *, int);
       
       void closeAllConns( void);
};





void * messageReceived( void * msg);
/* funkcja wysylajaca przesylke na dany adres*/
int sendMessage( Message msg);
void* run( void*);




#endif
